
#ifndef _SEFON_IOT_SHADOW_COMMON_H_
#define _SEFON_IOT_SHADOW_COMMON_H_


#include "SefonIotPlatform.h"
#include "SefonIotError.h"
#include "SefonIotTimer.h"
#include "SefonIotList.h"
#include "SefonIotShadow.h"
#include "SefonIotShadowConfig.h"
//typedef enum sfiot_shadow_action{
//    SFIOT_GET = 0,
//    SFIOT_PUSH = 1,
//}sfiot_shadow_method_t;

typedef struct sfiot_update_ack_wait_list_st {
    bool flag_busy; //0, free; 1, busy.
    char token[SDS_TOKEN_LEN];
    sfiot_cb_fpt callback;
    void *pcontext;
    sfiot_shadow_actions_t action;
    sfiot_time_t timer;
} sfiot_update_ack_wait_list_t, *sfiot_update_ack_wait_list_pt;

//typedef struct {
//    uint32_t base_system_time; //in millisecond
//    uint32_t epoch_time;
//} sfiot_shadow_time_t, *sfiot_shadow_time_pt;


typedef struct sfiot_inner_data_st {
    uint32_t token_num;
    uint32_t version; 
    //sfiot_shadow_time_t time;
    //sfiot_update_ack_wait_list_t update_ack_wait_list[SDS_UPDATE_WAIT_ACK_LIST_NUM];
    
    sfiot_cb_fpt callback;
    void *pcontext;
    list_t *attr_list;
    char *ptopic_update;
    char *ptopic_get;
    int32_t sync_status;
    char *devid;
    char * mqttpwd;
} sfiot_inner_data_t, *sfiot_inner_data_pt;;


typedef struct sfiot_shadow_st {
    void *mqtt;
    void *mutex;
    sfiot_inner_data_t inner_data;
} sfiot_shadow_t, *sfiot_shadow_pt;


sfiot_err_t SDSCommonFormatInit(sfiot_shadow_pt pshadow,
                                   format_data_pt pformat,
                                   const char* requestid,
                                   char *buf,
                                   uint16_t size,
                                   sfiot_shadow_actions_t action);

sfiot_err_t SDSCommonFormatAdd(sfiot_shadow_pt pshadow,
                                  format_data_pt pformat,
                                  const char *name,
                                  const void *pvalue,
                                  sfiot_shadow_attr_datatype_t datatype);

sfiot_err_t SDSCommonFormatFinalize(sfiot_shadow_pt pshadow, format_data_pt pformat, const char *tail_str);

//void SDSCommonUpdateTime(sfiot_shadow_pt pshadow, uint32_t new_timestamp);

int SDSCommonConvertData2string(
            char *buf,
            size_t buf_len,
            sfiot_shadow_attr_datatype_t type,
            const void *pData);

sfiot_err_t SDSCommonConvertString2data(
            const char *buf,
            size_t buf_len,
            sfiot_shadow_attr_datatype_t type,
            void *pData);

bool SDSCommonCheckAttrExistence(sfiot_shadow_pt pshadow, const sfiot_shadow_attr_pt pattr);
/*
sfiot_err_t SDSCommonRegisterAttr(
            sfiot_shadow_pt pshadow,
            sfiot_shadow_attr_pt pattr);

sfiot_err_t SDSCommonRemoveAttr(
            sfiot_shadow_pt pshadow,
            sfiot_shadow_attr_pt pattr);
*/
char *SDSCommonGenerateTopicName(sfiot_shadow_pt pshadow, sfiot_shadow_actions_t action);

sfiot_err_t SDSCommonPublish2update(sfiot_shadow_pt pshadow, char *data, uint32_t data_len);

void SDSCommonUpdateVersion(sfiot_shadow_pt pshadow, uint32_t version);

uint32_t SDSCommonGetVersion(sfiot_shadow_pt pshadow);

uint32_t SDSCommonGetTokennum(sfiot_shadow_pt pshadow);

#endif /* _SEFON_IOT_SHADOW_COMMON_H_ */
